package org.texteasy;

import java.util.ArrayList;
import java.util.HashSet;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.CharArrayBuffer;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.Contacts.Groups;
import android.provider.Contacts.Phones;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.ResourceCursorAdapter;
import android.widget.TextView;

import com.mobclix.android.sdk.MobclixAdView;
import com.mobclix.android.sdk.MobclixAdViewListener;
import com.mobclix.android.sdk.MobclixMMABannerXLAdView;

public class BulkMessenger extends ListActivity implements
		DialogInterface.OnClickListener, View.OnClickListener,  MobclixAdViewListener   {

	private static final String TAG = "BulkMessenger";

	private final static int NEW_MESSAGE_ID = Menu.FIRST;
	private final static int DISPLAY_GROUP_ID = Menu.FIRST + 1;
	private final static int SELECT_ALL_ID = Menu.FIRST + 2;
	private final static int UNSELECT_ALL_ID = Menu.FIRST + 3;
	private final static int SEARCH_ID = Menu.FIRST + 4;
	private final static int HELP = Menu.FIRST + 5;
	private final static int EDIT_SETTINGS = Menu.FIRST + 6;

	// private String[] projection = new String[] {People._ID,People.NAME,
	// People.TYPE, People.NUMBER};
	private String[] groupsProjection = new String[] { Groups._ID,
			Groups.SYSTEM_ID, Groups.NAME };
	// private Uri contacts = People.CONTENT_URI;
	private HashSet<String> selectedIds = new HashSet<String>();
	private long selectedGroupId = -1;
	private static final String SELECTED_GROUP_ID_PREFERENCE = "SelectedGroupId";
	private ArrayList<Long> displayGroupIds;
	private TextEasyDBAdapter dbAdaptor;
	private AlertDialog groupDialog;
	private boolean refreshQueryOnResume = false;
	private InputMethodManager inputMethodManager;

	private static final String PHONE_TYPE_HOME_PREFERENCE = "PHONE_TYPE_HOME";
	private static final String PHONE_TYPE_MOBILE_PREFERENCE = "PHONE_TYPE_MOBILE";
	private static final String PHONE_TYPE_WORK_PREFERENCE = "PHONE_TYPE_WORK";
	private static final String PHONE_TYPE_OTHER_PREFERENCE = "PHONE_TYPE_OTHER";
	private static final String PHONE_TYPE_CUSTOM_PREFERENCE = "PHONE_TYPE_CUSTOM";
	private static final String DISPLAY_ONLY_PRIMARY = "DISPLAY_ONLY_PRIMARY";

	private static final String PREV_PHONE_TYPE_HOME_PREFERENCE = "PREV_PHONE_TYPE_HOME";
	private static final String PREV_PHONE_TYPE_MOBILE_PREFERENCE = "PREV_PHONE_TYPE_MOBILE";
	private static final String PREV_PHONE_TYPE_WORK_PREFERENCE = "PREV_PHONE_TYPE_WORK";
	private static final String PREV_PHONE_TYPE_OTHER_PREFERENCE = "PREV_PHONE_TYPE_OTHER";
	private static final String PREV_PHONE_TYPE_CUSTOM_PREFERENCE = "PREV_PHONE_TYPE_CUSTOM";
	private static final String PREV_DISPLAY_ONLY_PRIMARY = "PREV_DISPLAY_ONLY_PRIMARY";
	
	static final int ID_COLUMN_INDEX = 0;
	static final int NAME_COLUMN_INDEX = 1;
	static final int TYPE_COLUMN_INDEX = 2;
	static final int NUMBER_COLUMN_INDEX = 3;
	static final int UNIQUE_NUMBER_COLUMN_INDEX = 4;

	public static final int GROUPS_COLUMN_INDEX_ID = 0;
	public static final int GROUPS_COLUMN_INDEX_SYSTEM_ID = 1;
	public static final int GROUPS_COLUMN_INDEX_NAME = 2;
	public static final int GROUPS_COLUMN_ACCOUNT_NAME = 3;
	public static final int GROUPS_COLUMN_ACCOUNT_TYPE = 4;

	private static final int DISPLAY_GROUPS_ALL_CONTACTS = 0;

	private ArrayList<Integer> selectedPhoneTypes = null;
	private boolean primaryNumbersOnly = false;

	private Handler handler = new Handler();
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		setContentView(R.layout.contacts_list);

		this.dbAdaptor = new TextEasyDBAdapter(this);
		this.dbAdaptor.open();
		
		MobclixMMABannerXLAdView bannerAd = (MobclixMMABannerXLAdView)findViewById(R.id.banner_adview);
		bannerAd.addMobclixAdViewListener(this);
		
		findViewById(R.id.btn_new_message).setOnClickListener(this);
		findViewById(R.id.btn_options).setOnClickListener(this);
		findViewById(R.id.btn_search).setOnClickListener(this);
		findViewById(R.id.TextEasyBanner).setOnClickListener(this);
		inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
		
		Configuration config = getResources().getConfiguration();
        if(config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO){
    		findViewById(R.id.btn_search).setVisibility(View.GONE); 
        }

		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(this);
		selectedGroupId = prefs.getLong(SELECTED_GROUP_ID_PREFERENCE, -1);

		checkPhoneTypePreferences(prefs);
		updateSelectedPhoneTypes(prefs);
		boolean storeSelections = prefs.getBoolean(
				getString(R.string.REMEMBER_SELECTIONS), false);
		if (!storeSelections) {

			if (getLastNonConfigurationInstance() != null) {
				this.selectedIds = (HashSet<String>) getLastNonConfigurationInstance();
			}
		}

		ListView listView = getListView();
		listView.setItemsCanFocus(false);
		listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
		listView.setTextFilterEnabled(true);
		queryContacts();
		
		if(!prefs.getBoolean(WhatsNewDialog.WHATS_NEW, false)){
			this.handler.postDelayed(new Runnable(){
				@Override
				public void run() {
					backupPhoneTypePreferences();
					startActivity(new Intent(BulkMessenger.this, WhatsNewDialog.class));
				}
			}, 1000);
		}
	}

	private void checkPhoneTypePreferences(SharedPreferences prefs) {

		boolean needsUpdate = false;
		Editor editor = prefs.edit();
		if (!prefs.contains(PHONE_TYPE_CUSTOM_PREFERENCE)) {
			editor.putBoolean(PHONE_TYPE_CUSTOM_PREFERENCE, true);
			needsUpdate = true;
		}

		if (!prefs.contains(PHONE_TYPE_HOME_PREFERENCE)) {
			editor.putBoolean(PHONE_TYPE_HOME_PREFERENCE, true);
			needsUpdate = true;
		}

		if (!prefs.contains(PHONE_TYPE_MOBILE_PREFERENCE)) {
			editor.putBoolean(PHONE_TYPE_MOBILE_PREFERENCE, true);
			needsUpdate = true;
		}

		if (!prefs.contains(PHONE_TYPE_OTHER_PREFERENCE)) {
			editor.putBoolean(PHONE_TYPE_OTHER_PREFERENCE, true);
			needsUpdate = true;
		}

		if (!prefs.contains(PHONE_TYPE_WORK_PREFERENCE)) {
			editor.putBoolean(PHONE_TYPE_WORK_PREFERENCE, true);
			needsUpdate = true;
		}

		if (needsUpdate) {
			editor.commit();
		}
	}

	/**
	 * Utility method for displaying querying contacts and displaying them
	 * 
	 * @param nameClause
	 */
	private void queryContacts() {

		Cursor managedCursor = ContactsAccessor.getInstance()
				.queryContacts(getContentResolver(), null, selectedGroupId,
						selectedPhoneTypes, this.primaryNumbersOnly);

		ResourceCursorAdapter contactsAdaptor = new ContactItemListAdapter(
				this, R.layout.contacts_row, managedCursor);
		setListAdapter(contactsAdaptor);
	}

	@Override
	protected void onPause() {
		super.onPause();

		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(this);
		boolean storeSelections = prefs.getBoolean(
				getString(R.string.REMEMBER_SELECTIONS), false);

		if (storeSelections) {
			HashSet<String> selectedIds = this.selectedIds;
			if (selectedIds != null && !selectedIds.isEmpty()) {
				this.dbAdaptor.persistSelectedIds(selectedIds);
			}
		}

		this.dbAdaptor.close();

		if (groupDialog != null && groupDialog.isShowing()) {
			groupDialog.dismiss();
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();

		if (this.dbAdaptor.isOpen()) {
			this.dbAdaptor.close();
		}
	}

	@Override
    protected void onResume() {
    	super.onResume();
    	this.dbAdaptor.open();
    	
    	findViewById(R.id.btn_new_message).setEnabled(true);
    	
    	SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
        boolean storeSelections = prefs.getBoolean(getString(R.string.REMEMBER_SELECTIONS), false);
        if(storeSelections){
        	this.selectedIds = this.dbAdaptor.getSelectedIdsAndClear();
        }
        
        boolean clearSelectedIds = false;
        //if the prev preference is true and the current is false then the
        //user has filtered phones and any selections are invalid
        if(prefs.getBoolean(PREV_PHONE_TYPE_CUSTOM_PREFERENCE, false) && 
    		!prefs.getBoolean(PHONE_TYPE_CUSTOM_PREFERENCE, false)){
        	
        	clearSelectedIds =true;
        }else if(prefs.getBoolean(PREV_PHONE_TYPE_HOME_PREFERENCE, false) && 
    		!prefs.getBoolean(PHONE_TYPE_HOME_PREFERENCE, false)){
        	
        	clearSelectedIds =true;
        }else if(prefs.getBoolean(PREV_PHONE_TYPE_MOBILE_PREFERENCE, false) && 
        		!prefs.getBoolean(PHONE_TYPE_MOBILE_PREFERENCE, false)){
            	
        	clearSelectedIds =true;
        }else if(prefs.getBoolean(PREV_PHONE_TYPE_OTHER_PREFERENCE, false) && 
        		!prefs.getBoolean(PHONE_TYPE_OTHER_PREFERENCE, false)){
            	
        	clearSelectedIds =true;
        }else if(prefs.getBoolean(PREV_PHONE_TYPE_WORK_PREFERENCE, false) && 
        		!prefs.getBoolean(PHONE_TYPE_WORK_PREFERENCE, false)){
            	
        	clearSelectedIds =true;
        }else if(!prefs.getBoolean(PREV_DISPLAY_ONLY_PRIMARY, false) && 
        		prefs.getBoolean(DISPLAY_ONLY_PRIMARY, false)){
            	
        	clearSelectedIds =true;
        }
        
        if(clearSelectedIds){
        	this.selectedIds = new HashSet<String>();
        	backupPhoneTypePreferences();
			getListView().setFilterText("A");
			getListView().clearTextFilter();
        }
        
        //hide the menu bar if HIDE_MENU_BAR is checked
        if(prefs.getBoolean(getString(R.string.HIDE_MENU_BAR), false)){
        	findViewById(R.id.btn_bar).setVisibility(View.GONE);
        }else{
        	findViewById(R.id.btn_bar).setVisibility(View.VISIBLE);
        }
        
        updateSelectedPhoneTypes(prefs);
        
        if(refreshQueryOnResume){
        	refreshQueryOnResume = false;
        	queryContacts();
        }
    }

	private void updateSelectedPhoneTypes(SharedPreferences prefs) {
		// update the selectedPhoneTypes
		ArrayList<Integer> phoneTypesToFilter = new ArrayList<Integer>();
		if (prefs.getBoolean(PHONE_TYPE_CUSTOM_PREFERENCE, false)) {
			phoneTypesToFilter.add(Phones.TYPE_CUSTOM);
		}

		if (prefs.getBoolean(PHONE_TYPE_HOME_PREFERENCE, false)) {
			phoneTypesToFilter.add(Phones.TYPE_HOME);
		}

		if (prefs.getBoolean(PHONE_TYPE_MOBILE_PREFERENCE, false)) {
			phoneTypesToFilter.add(Phones.TYPE_MOBILE);
		}

		if (prefs.getBoolean(PHONE_TYPE_OTHER_PREFERENCE, false)) {
			phoneTypesToFilter.add(Phones.TYPE_OTHER);
		}

		if (prefs.getBoolean(PHONE_TYPE_WORK_PREFERENCE, false)) {
			phoneTypesToFilter.add(Phones.TYPE_WORK);
		}

		this.selectedPhoneTypes = phoneTypesToFilter;
		
		if(prefs.getBoolean(DISPLAY_ONLY_PRIMARY, false)){
			this.primaryNumbersOnly = true;
		}else{
			this.primaryNumbersOnly = false;
		}
	}

	@Override
	public Object onRetainNonConfigurationInstance() {

		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(this);
		boolean storeSelections = prefs.getBoolean(
				getString(R.string.REMEMBER_SELECTIONS), false);

		if (!storeSelections) {
			return this.selectedIds;
		} else {
			return null;
		}
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);

		SharedPreferences prefs = PreferenceManager
				.getDefaultSharedPreferences(this);
		// Only show new Message in options if hide menu bar is checked
		boolean hidMenuBar = prefs.getBoolean(
				getString(R.string.HIDE_MENU_BAR), false);
		if (hidMenuBar && menu.findItem(NEW_MESSAGE_ID) == null) {
			menu.add(Menu.NONE, NEW_MESSAGE_ID, 0, R.string.NEW_MESSAGE);
			Configuration config = getResources().getConfiguration();
	        if(config.hardKeyboardHidden != Configuration.HARDKEYBOARDHIDDEN_NO){
	        	menu.add(Menu.NONE, SEARCH_ID, SEARCH_ID, R.string.SEARCH);
	        }
		} else if (!hidMenuBar) {
			menu.removeItem(NEW_MESSAGE_ID);
			menu.removeItem(SEARCH_ID);
		}

		return true;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(Menu.NONE, DISPLAY_GROUP_ID, DISPLAY_GROUP_ID, R.string.DISPLAY_GROUPS);
		menu.add(Menu.NONE, SELECT_ALL_ID, SELECT_ALL_ID, R.string.SELECT_ALL);
		menu.add(Menu.NONE, UNSELECT_ALL_ID, UNSELECT_ALL_ID, R.string.UNSELECT_ALL);
		menu.add(Menu.NONE, HELP, HELP, R.string.Help);
		menu.add(Menu.NONE, EDIT_SETTINGS, EDIT_SETTINGS, R.string.SETTINGS);
		return true;
	}

	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		super.onListItemClick(l, v, position, id);

		Cursor cursor = (Cursor) getListView().getItemAtPosition(position);
		long contactId = cursor.getLong(ID_COLUMN_INDEX);
		long uniqueNumberId = -1;

		if (!cursor.isNull(TYPE_COLUMN_INDEX)) {
			uniqueNumberId = cursor.getInt(UNIQUE_NUMBER_COLUMN_INDEX);
		}

		String clickedContact = contactId + "|" + uniqueNumberId;

		HashSet<String> selectedIds = this.selectedIds;
		if (selectedIds.contains(clickedContact)) {
			selectedIds.remove(clickedContact);
		} else {
			selectedIds.add(clickedContact);
		}
	}

	Cursor doFilter(String filter) {
		final ContentResolver resolver = getContentResolver();

		return ContactsAccessor.getInstance().queryContacts(resolver, filter,
				selectedGroupId, selectedPhoneTypes, this.primaryNumbersOnly);
	}

	public String keywords() {
		return "bulk text, mass text, select contacts, select groups";
	}
	
	public void onCustomAdTouchThrough(MobclixAdView arg0, String arg1) {
	}
	
	public void onFailedLoad(MobclixAdView v, int arg1) {
		Log.i(getClass().getSimpleName(), "Error code: " + arg1);
		v.pause();
		View view = findViewById(R.id.progress_bar);
		view.setVisibility(View.GONE);
		view = findViewById(R.id.banner_adview);
		view.setVisibility(View.GONE);
		//if the add is disabled then hide everything, else show the 
		//emergency banner
		if(arg1 != MobclixAdViewListener.ADSIZE_DISABLED){
			view = findViewById(R.id.TextEasyBanner);
			view.setVisibility(View.VISIBLE);
		}
	}
	
	public void onSuccessfulLoad(MobclixAdView arg0) {
		View view = findViewById(R.id.progress_bar);
		view.setVisibility(View.GONE);
		//textEasyBanner should already have visibility gone, but
		//just in case
		view = findViewById(R.id.TextEasyBanner);
		view.setVisibility(View.GONE);
		view = findViewById(R.id.banner_adview);
		view.setVisibility(View.VISIBLE);
	}
	
	@Override
	public boolean onOpenAllocationLoad(MobclixAdView arg0, int arg1) {
		// TODO Auto-generated method stub
		return false;
	}
	
	@Override
	public void onAdClick(MobclixAdView arg0) {
		// TODO Auto-generated method stub
		
	}
	
	public String query() {
		return null;
	}
	
	
	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		
		if(keyCode == KeyEvent.KEYCODE_SEARCH){
			inputMethodManager.toggleSoftInputFromWindow(findViewById(R.id.btn_search).getWindowToken(), 
				InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
			return true;
		}
		
		return super.onKeyUp(keyCode, event);
	}
	
	public void onClick(View v) {

		switch (v.getId()) {
		case R.id.btn_new_message: {
			createNewMessage();
			break;
		}
		case R.id.btn_options: {
			getWindow().openPanel(Window.FEATURE_OPTIONS_PANEL,
					new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU));
			getWindow().openPanel(Window.FEATURE_OPTIONS_PANEL,
					new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU));
			break;
		}
		case R.id.btn_search:{
			inputMethodManager.toggleSoftInputFromWindow(
				findViewById(R.id.btn_search).getWindowToken(), 
				InputMethodManager.SHOW_FORCED, 
				InputMethodManager.HIDE_IMPLICIT_ONLY);
			break;
		}
		case R.id.TextEasyBanner:{
			
			final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
			emailIntent .setType("plain/text");
			emailIntent .putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"texteasy.android@gmail.com"});
			emailIntent .putExtra(android.content.Intent.EXTRA_SUBJECT, "Text Easy comment");
			startActivity(Intent.createChooser(emailIntent, "Send mail..."));
			break;
		}
		}

	}

	public void onClick(DialogInterface dialogInterface, int which) {

		if(dialogInterface == groupDialog){
			if (which == DialogInterface.BUTTON1) {
	
				SharedPreferences prefs = PreferenceManager
						.getDefaultSharedPreferences(this);
				prefs.edit().putLong(SELECTED_GROUP_ID_PREFERENCE, selectedGroupId)
						.commit();
	
				this.selectedIds = new HashSet<String>();
				getListView().setFilterText("A");
				getListView().clearTextFilter();
			} else {
				// user just selected an option
				selectedGroupId = this.displayGroupIds.get(which);
			}
		}

	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {

		switch (item.getItemId()) {
		case NEW_MESSAGE_ID:
			createNewMessage();
			break;
		case DISPLAY_GROUP_ID:
			createGroupAlertDialog();
			break;
		case SELECT_ALL_ID:
			selectAll();
			break;
		case EDIT_SETTINGS:
			refreshQueryOnResume = true;

			backupPhoneTypePreferences();
			startActivity(new Intent(this, TextEasyPreferences.class));
			return (true);
		case HELP:
			
			showHelpDialog();
			break;
		case UNSELECT_ALL_ID:
			this.selectedIds = new HashSet<String>();
			getListView().clearTextFilter();
			((ContactItemListAdapter)getListAdapter()).notifyDataSetChanged();
			break;
		case SEARCH_ID:
			inputMethodManager.toggleSoftInputFromWindow(
				findViewById(R.id.btn_search).getWindowToken(), 
				InputMethodManager.SHOW_FORCED, 
				InputMethodManager.HIDE_IMPLICIT_ONLY);
			break;
		}

		return super.onMenuItemSelected(featureId, item);
	}

	private void showHelpDialog(){
		
		//from the help users can go into the phone filters prefs which
		//means they can hide there current selections so backup
		//prefs so we can detect changes and clear selections
		backupPhoneTypePreferences();
		startActivity(new Intent(this, WhatsNewDialog.class));
	}
	
	private void backupPhoneTypePreferences() {
		// Before going to settings, save the phoneTypeFilters so that changes
		// can be detected. If there are changes(only true->false) then remove
		// any selected contacts. If we don't clear selected contacts on filter
		// changes then can send text to selected contact you can't see
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
		Editor editor = prefs.edit();

		editor.putBoolean(PREV_PHONE_TYPE_CUSTOM_PREFERENCE, prefs
				.getBoolean(PHONE_TYPE_CUSTOM_PREFERENCE, false));
		editor.putBoolean(PREV_PHONE_TYPE_HOME_PREFERENCE, prefs
				.getBoolean(PHONE_TYPE_HOME_PREFERENCE, false));
		editor.putBoolean(PREV_PHONE_TYPE_MOBILE_PREFERENCE, prefs
				.getBoolean(PHONE_TYPE_MOBILE_PREFERENCE, false));
		editor.putBoolean(PREV_PHONE_TYPE_OTHER_PREFERENCE, prefs
				.getBoolean(PHONE_TYPE_OTHER_PREFERENCE, false));
		editor.putBoolean(PREV_PHONE_TYPE_WORK_PREFERENCE, prefs
				.getBoolean(PHONE_TYPE_WORK_PREFERENCE, false));
		editor.putBoolean(PREV_DISPLAY_ONLY_PRIMARY, prefs
				.getBoolean(DISPLAY_ONLY_PRIMARY, false));
		editor.commit();
	}

	private void selectAll() {

		// Log.e(TAG, "selectAll start");

		Cursor managedCursor = ContactsAccessor.getInstance()
				.queryContacts(getContentResolver(), null, selectedGroupId,
				selectedPhoneTypes, this.primaryNumbersOnly);

		// Log.e(TAG, "selectAll after query");

		HashSet<String> selectedIds = this.selectedIds;

		while (managedCursor.moveToNext()) {

			Long id = managedCursor.getLong(ID_COLUMN_INDEX);
			Long uniquePhoneId = managedCursor
					.getLong(UNIQUE_NUMBER_COLUMN_INDEX);

			// if(!selectedIds.contains(id)){
			selectedIds.add(id + "|" + uniquePhoneId);
			// }
		}

		// Log.e(TAG, "selectAll after selection");

		getListView().clearTextFilter();
		((ContactItemListAdapter)getListAdapter()).notifyDataSetChanged();

		// Log.e(TAG, "after textFilter update");

	}

	/*
	 * private void createSignatureDialog(){
	 * 
	 * LayoutInflater factory = LayoutInflater.from(this); final View
	 * textEntryView = factory.inflate(R.layout.signature_dialog_entry, null);
	 * 
	 * signatureDialog = new AlertDialog.Builder(this)
	 * .setTitle(R.string.ADD_SIGNATURE_TITLE)
	 * .setPositiveButton(android.R.string.ok, this)
	 * .setNegativeButton(android.R.string.cancel, null).
	 * setView(textEntryView).create();
	 * 
	 * signatureDialog.show(); }
	 */

	private void createGroupAlertDialog() {

		ArrayList<Long> groupIds = new ArrayList<Long>();
		ArrayList<GroupListItem> groups =  ContactsAccessor.getInstance().queryGroups(
				this, getContentResolver());
		
		for(GroupListItem group: groups){
			groupIds.add(group.groupId);
		}
		
		this.displayGroupIds = groupIds;

		groupDialog = new AlertDialog.Builder(this).setTitle(
				R.string.SELECT_GROUP_TITLE).setPositiveButton(
				android.R.string.ok, this).setNegativeButton(
				android.R.string.cancel, null).setSingleChoiceItems(
				new GroupListAdapter(this, R.layout.group_row, groups),
				//set the selectedIndex to 0 so the first item in the list is 
				//always displayed
				0, this).create();
		groupDialog.show();
	}

	private void createNewMessage() {

		findViewById(R.id.btn_new_message).setEnabled(false);
		setProgressBarIndeterminateVisibility(true);
		
		final HashSet<String> selectedIds = new HashSet<String>(this.selectedIds);
		if (selectedIds.isEmpty()) {
			setProgressBarIndeterminateVisibility(false);
			findViewById(R.id.btn_new_message).setEnabled(true);
			return;
		}

		new AsyncTask<Void, Void, Pair<String,Integer>>() {
			
			@Override
			protected Pair<String,Integer> doInBackground(Void... unused) {
				HashSet<Long> onlyIds = new HashSet<Long>();
				for (String selectedId : selectedIds) {
					String[] tokens = selectedId.split("\\|");
					onlyIds.add(new Long(tokens[0]));
				}

				String numberSeperator = ";";
				if(useCommaAsSeperator()){
					
					numberSeperator = ",";
				}
				
				Cursor managedCursor = ContactsAccessor.getInstance()
						.queryContactsForPhoneNumbers(getContentResolver(),
								onlyIds);

				// Log.e(TAG, "before iterating createNewMessage");
				int count = 0;
				StringBuffer buffer = new StringBuffer();
				if (managedCursor != null) {
					while (managedCursor.moveToNext()) {

						Long contactId = managedCursor.getLong(0);
						Long uniquePhoneId = managedCursor.getLong(2);

						if (selectedIds.contains(contactId + "|"
								+ uniquePhoneId)) {

							// skip null or blank values
							String phoneNumber = managedCursor
									.getString(managedCursor.getColumnIndexOrThrow(
									ContactsAccessor.getInstance().getPhoneColumnIndex()));
							
							if (phoneNumber != null && 
								!"".equals(phoneNumber.trim())){
								
								buffer.append(phoneNumber).append(numberSeperator);
								count++;
							}
						}
					}
				}

				// Log.e(TAG, "after query createNewMessage");
				if (buffer.length() != 0) {
					String numbers = buffer.substring(0,
							buffer.length() - 1);

					return Pair.create(numbers, count);
				} else {
					return null;
				}
			}

			@Override
			protected void onPostExecute(Pair<String,Integer> result) {
				
				if(result == null){
					setProgressBarIndeterminateVisibility(false);
					findViewById(R.id.btn_new_message).setEnabled(true);
					return;
				}
				
				SharedPreferences prefs = PreferenceManager
					.getDefaultSharedPreferences(BulkMessenger.this);
				
				if(result.getRight() > WarningActivity.GENERAL_WARNING_COUNT || 
					(!prefs.getBoolean(getString(R.string.VERIZON_WARNING_PREF), false) &&  
					result.getRight() > WarningActivity.VERIZON_WARNING_COUNT) ){
					
					//forward numbers to warning activity. It will take 
					//care of sending the message
					Intent warningActivity = new Intent(BulkMessenger.this, WarningActivity.class);
					warningActivity.putExtra(WarningActivity.NUMBERS_EXTRAS, result.getLeft());
					warningActivity.putExtra(WarningActivity.COUNT_EXTRAS, result.getRight());
					startActivity(warningActivity);
					setProgressBarIndeterminateVisibility(false);
				}else{
					
					
					Intent i = new Intent();
					i.setAction(Intent.ACTION_VIEW);
					i.setType("vnd.android-dir/mms-sms");
					i.putExtra("address", result.getLeft());
					if(useCommaAsSeperator()){
						//if using a comma then other third party messaging may break
						//the plan is to check if the default messaging app exists and 
						//if so force that selection
						Intent testIntent = new Intent();
						testIntent.setAction(Intent.ACTION_VIEW);
						testIntent.setType("vnd.android-dir/mms-sms");
						
						for(ResolveInfo info: getPackageManager().queryIntentActivities(testIntent, 0)){
				        	if("com.android.mms".equalsIgnoreCase(info.activityInfo.packageName.toString())){
				        		i.setComponent(new ComponentName(info.activityInfo.packageName, info.activityInfo.name));
				        		break;
				        	}
				        }
					}
					
					
					String signature = prefs.getString(
							getString(R.string.ADD_SIGNATURE_TITLE), "");
					if (signature != null && !signature.equals("")) {
						i.putExtra("sms_body", "\n" + signature);
					}
					
					startActivity(i);
					setProgressBarIndeterminateVisibility(false);
				}

			}
		}.execute();
		
	}

	/**
	 * The unoffical sperator for text message contacts is the ;. Some phones use a
	 * comma. 
	 * @return
	 */
	public static boolean useCommaAsSeperator(){
		
		if("SGH-T959".equalsIgnoreCase(Build.MODEL) || 
			"SGH-I897".equalsIgnoreCase(Build.MODEL) || 
			"GT-I9000".equalsIgnoreCase(Build.MODEL) ||
			"SPH-d700".equalsIgnoreCase(Build.MODEL) ||
			"SCH-I500".equalsIgnoreCase(Build.MODEL)){
			
			return true;
		}
		
		return false;
	}
	
	final static class GroupListItem{
		public final Long groupId;
		public final String groupName;
		public final String accountName;
		public final String accountType;
		
		public GroupListItem(Long groupId, String groupName, String accountName, 
			String accountType){
			
			this.groupId= groupId;
			this.groupName = groupName;
			this.accountName = accountName;
			this.accountType = accountType;
		}
	}

	private final class GroupListAdapter extends ArrayAdapter<GroupListItem>{
		
		private LayoutInflater mInflater;
		private int resource;
		
		public GroupListAdapter(Context context, int viewResourceId, ArrayList<GroupListItem> items) {
			super(context, viewResourceId, items);
			
			mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			this.resource = viewResourceId;
			
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			
			View view;
			
			if (convertView == null) {
	            view = mInflater.inflate(this.resource, parent, false);
	        } else {
	            view = convertView;
	        }
			
			GroupListItem item = getItem(position);
			
			TextView name = (TextView)view.findViewById(R.id.group_name);
			name.setText(item.groupName);
			TextView accountName = (TextView)view.findViewById(R.id.account_name);
			if(item.accountName != null){
				accountName.setText(item.accountName);
				accountName.setVisibility(View.VISIBLE);
			}else{
				accountName.setText("");
				//accountName.setVisibility(View.GONE);
			}
			TextView accountType = (TextView)view.findViewById(R.id.account_type);
			if(item.accountType != null){
				accountType.setText(item.accountType);
				accountType.setVisibility(View.VISIBLE);
			}else{
				accountType.setText("");
				//accountType.setVisibility(View.GONE);
			}
			
			RadioButton button = (RadioButton)view.findViewById(R.id.group_selected);
			//selectedGroupIndex
			//selectedGroupId
			if(selectedGroupId == item.groupId){
				button.setChecked(true);
			}else{
				button.setChecked(false);
			}
			
			return view;
		}
	}
	
	final static class ContactListItemCache {
		public TextView nameView;
		public CharArrayBuffer nameBuffer = new CharArrayBuffer(128);
		public TextView labelView;
		public CharArrayBuffer labelBuffer = new CharArrayBuffer(128);
		public TextView numberView;
		public CharArrayBuffer numberBuffer = new CharArrayBuffer(128);
		public CheckBox checkBox;
		public boolean checked;

	}
	
	private final class ContactItemListAdapter extends ResourceCursorAdapter {

		private CharSequence[] mLocalizedLabels;
		private CharSequence mUnknownNameText;

		public ContactItemListAdapter(Context context, int resource,
				Cursor cursor) {
			super(context, resource, cursor);

			final Resources resources = context.getResources();
			mLocalizedLabels = resources
					.getStringArray(android.R.array.phoneTypes);

			mUnknownNameText = context.getText(android.R.string.unknownName);
		}

		@Override
		public View newView(Context context, Cursor cursor, ViewGroup parent) {
			final View view = super.newView(context, cursor, parent);

			final ContactListItemCache cache = new ContactListItemCache();
			cache.nameView = (TextView) view.findViewById(R.id.name);
			cache.labelView = (TextView) view.findViewById(R.id.label);
			cache.labelView.setCompoundDrawablePadding(3);
			cache.numberView = (TextView) view.findViewById(R.id.number);
			cache.checkBox = (CheckBox) view.findViewById(R.id.selected);
			view.setTag(cache);

			return view;

		}

		@Override
		public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
			return doFilter(constraint.toString());
		}

		@Override
		public void bindView(View view, Context context, Cursor cursor) {

			final ContactListItemCache cache = (ContactListItemCache) view
					.getTag();

			// Set the name
			cursor.copyStringToBuffer(NAME_COLUMN_INDEX, cache.nameBuffer);
			int size = cache.nameBuffer.sizeCopied;
			if (size != 0) {
				cache.nameView.setText(cache.nameBuffer.data, 0, size);
			} else {
				cache.nameView.setText(mUnknownNameText);
			}

			// Set the phone number
			TextView numberView = cache.numberView;
			cursor.copyStringToBuffer(NUMBER_COLUMN_INDEX, cache.numberBuffer);
			size = cache.numberBuffer.sizeCopied;
			if (size != 0) {
				numberView.setText(cache.numberBuffer.data, 0, size);
				numberView.setVisibility(View.VISIBLE);
			} else {
				numberView.setVisibility(View.GONE);
			}

			int typeCustom = ContactsAccessor.getInstance().getPhoneTypeCustom();
			int typeHome = ContactsAccessor.getInstance().getPhoneTypeHome();
			
			// Set the label
			int type = -1;
			TextView labelView = cache.labelView;
			if (!cursor.isNull(TYPE_COLUMN_INDEX)) {
				type = cursor.getInt(TYPE_COLUMN_INDEX);
				
				if (type != typeCustom) {
					try {
						labelView.setText(mLocalizedLabels[type - 1]);
					} catch (ArrayIndexOutOfBoundsException e) {
						labelView.setText(mLocalizedLabels[typeHome - 1]);
					}
				} else {
					// Set the text to a length of 0
					labelView.setText(cache.labelBuffer.data, 0, 0);
				}
			} else {
				// Set the text to a length of 0
				labelView.setText(cache.labelBuffer.data, 0, 0);
			}

			long uniqueNumberId = cursor.getLong(UNIQUE_NUMBER_COLUMN_INDEX);
			long contactId = cursor.getLong(ID_COLUMN_INDEX);
			if (selectedIds.contains(contactId + "|" + uniqueNumberId)) {
				cache.checkBox.setChecked(true);
			} else {
				cache.checkBox.setChecked(false);
			}

		}

	}
	
}